package wkt.exam;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import net.xnzn.framework.config.exception.BizRuntimeException;
import net.xnzn.framework.data.mybatis.Paging;
import net.xnzn.framework.id.Id;
import net.xnzn.framework.secure.filter.annotation.RequiresAuthentication;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import wkt.RequireStudentLogin;
import wkt.WebUtils;
import wkt.basic.Basic;
import wkt.basic.BasicExamDate;
import wkt.basic.BasicExamDateMapper;
import wkt.basic.BasicMapper;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/exam-mock")
@Validated

public class ExamMockController {
    @Autowired
    private ExamMockMapper examMockMapper;
    @Autowired
    private BasicMapper basicMapper;
    @Autowired
    private BasicExamDateMapper basicExamDateMapper;

    @PostMapping("/list/{pageSize}/{pageNum}")
    @RequiresAuthentication
    public Paging<ExamMock> list(@RequestBody ExamMock examMock, @PathVariable @Range(min = 1, max = 100, message = "请输入1-100") int pageSize, @PathVariable int pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        final List<ExamMock> list = examMockMapper.list(examMock);
        if (CollUtil.isEmpty(list)) return Paging.build(list);

        final List<BasicExamDate> basicExamDates = basicExamDateMapper.selectList(Wrappers.lambdaQuery(BasicExamDate.class)
                .select(BasicExamDate::getId, BasicExamDate::getBasicId, BasicExamDate::getDate)
                .in(BasicExamDate::getId, list.stream().map(ExamMock::getExamDateId).collect(Collectors.toSet())));
        final Map<Long, BasicExamDate> examDateId_examDate = basicExamDates.stream().collect(Collectors.toMap(BasicExamDate::getId, Function.identity(), (o, n) -> n));

        List<Basic> zhuanyes = basicMapper.selectList(Wrappers.lambdaQuery(Basic.class)
                .select(Basic::getId, Basic::getName, Basic::getCode, Basic::getType, Basic::getParentId)
                .in(Basic::getId, basicExamDates.stream().map(BasicExamDate::getBasicId).collect(Collectors.toSet())));
        final Map<Long, Basic> basicId_zhuanye = zhuanyes.stream().collect(Collectors.toMap(Basic::getId, Function.identity(), (o, n) -> n));

        List<Basic> cencis = basicMapper.selectList(Wrappers.lambdaQuery(Basic.class)
                .select(Basic::getId, Basic::getName, Basic::getCode, Basic::getType, Basic::getParentId)
                .in(Basic::getId, zhuanyes.stream().map(Basic::getParentId).collect(Collectors.toSet())));
        final Map<Long, Basic> basicId_cencis = cencis.stream().collect(Collectors.toMap(Basic::getId, Function.identity(), (o, n) -> n));

        list.forEach(examMock1 -> {
            examMock1.setExamDate(examDateId_examDate.get(examMock1.getExamDateId()));
            examMock1.setZhuanye(basicId_zhuanye.get(examMock1.getExamDate().getBasicId()));
            examMock1.setCenci(basicId_cencis.get(examMock1.getZhuanye().getParentId()));
        });
        return Paging.build(list);
    }

    @PostMapping("/get")
    @RequiresAuthentication
    public ExamMock getExamDate(@RequestBody ExamMock examMock) {
        return examMockMapper.get(examMock.getId(), null);
    }

    @PostMapping("/get-my")
    @RequireStudentLogin
    public ExamMock getMy() {
        return examMockMapper.get(null, WebUtils.studentId());
    }

    @PostMapping("/upsert")
    @RequireStudentLogin
    public void upsert(@RequestBody ExamMock examMock) {
        final ExamMock my = getMy();
        if (my == null) {
            examMock.setId(Id.next());
            examMock.setStudentId(WebUtils.studentId());
            examMockMapper.insert(examMock);
            return;
        }
        if ("已寄出".equals(my.getSendState())) {
            throw new BizRuntimeException("模拟试卷已寄出,无法修改收货地址");
        }
        examMockMapper.update(null, Wrappers.lambdaUpdate(ExamMock.class).eq(ExamMock::getStudentId, WebUtils.studentId())
                .set(ExamMock::getName, examMock.getName())
                .set(ExamMock::getMobile, examMock.getMobile())
                .set(ExamMock::getAddr, examMock.getAddr())
                .set(ExamMock::getPcdCode, examMock.getPcdCode())
                .set(ExamMock::getPcdName, examMock.getPcdName())
        );
    }


    @PostMapping("/delete")
    @RequiresAuthentication
    public void deleteExamDate(@RequestBody ExamMock examMock) {
        examMockMapper.update(null, Wrappers.lambdaUpdate(ExamMock.class)
                .eq(ExamMock::getId, examMock.getId())
                .set(ExamMock::getState, "DELETE"));
    }

    @PostMapping("/update-send-state")
    @RequiresAuthentication
    public void update(@RequestBody ExamMock examMock) {
        examMockMapper.update(null, Wrappers.lambdaUpdate(ExamMock.class)
                .eq(ExamMock::getId, examMock.getId())
                .set(ExamMock::getSendState, examMock.getSendState())
        );
    }
}
